;var validate = (function(global, $, undefined) {   
	"use strict";
	if (!$) {
		throw "Validate requires jQuery"; // jQuery is not loaded.
	}
     $.fn.isOnScreen = function(){     
        var win = $(global);
        var viewport = {
            top : win.scrollTop(),
            left : win.scrollLeft()
        };
        viewport.right = viewport.left + win.width();
        viewport.bottom = viewport.top + win.height();     
        var bounds = this.offset();
        bounds.right = bounds.left + this.outerWidth();
        bounds.bottom = bounds.top + this.outerHeight();     
        return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));     
    };
	 function getCheckStr(obj) {
			obj = $(obj);
			var val;
			if (obj.val()==obj.attr('defValue'))
			{
				val = '';
			} else {
				val = $.trim(obj.val());
			}
			return val;
		}
    var checkfns = {
		//函数作用：判断对象的值是否为空(true: 为空)	
		isBlank:function (obj)
		{
			return /^[\s　]*$/.test(getCheckStr(obj));
		},
        //函数作用：判断对象的值是否太简单(true：否; false: 是)
        isSimple:function (obj,isCheckBool)
        {
            var val = getCheckStr(obj);
            if(!isCheckBool && (val == '' || val == null)) return false;
            return !(/[\u4E00-\u9FA5\uF900-\uFA2D]|[a-zA-Z]/.test(val));
        },
		//函数作用：检索是否含有汉字(true: 不包含; false: 包含)  isCheckBool是否为require
		checkWord:function (obj,isCheckBool)
		{
			var val = getCheckStr(obj);
			if(!isCheckBool && (val == '' || val == null)) return true;
			return /[\u4e00-\u9fa5]/.test(val);
		},
		//函数作用：检索是否为英文单词(true: 是; false: 否)  isCheckBool是否为require
		checkEnWord:function (obj,isCheckBool)
		{
			var val = getCheckStr(obj);
			if(!isCheckBool && (val == '' || val == null)) return true;
			return /^[a-zA-Z0-9]+$/.test(val);
		},
		//函数作用：检索Email格式是否有效
		checkMail:function (obj,isCheckBool)
		{
			var val = getCheckStr(obj);
			if(!isCheckBool && (val == '' || val == null)) return true;
			return /^\s*\w+([-+.]\w+)*@\w+([-.]\w+)*(\.\w+([-.]\w+)*){1,2}\s*$/i.test(val);
		},
		//函数作用：检索密码是否有效(空格以外的所有字符均有效)
		checkPwd:function (obj) 
		{
			obj = $(obj);
			var val = obj.val();
			return /\s/.test(val);
		},
		//函数作用：检索电话号码格式是否有效
		checkPhone:function (obj,isCheckBool)
		{
			var val = getCheckStr(obj);
			if(!isCheckBool && (val == '' || val == null)) return true;
			var reg = /^([\d\uFF10-\uFF19]{2,5}[-\uFF0D])?([\d\uFF10-\uFF19]{3,5}[-\uFF0D])?[1-9\uFF11-\uFF19]{1}[\d\uFF10-\uFF19]{5,7}([-\uFF0D][1-9\uFF11-\uFF19]{1}[\d\uFF10-\uFF19]{1,3})?$/;
			var reg2 = /^[\d\uFF10-\uFF19]{7,12}$/;
			return reg.test(val) || reg2.test(val);
		},
		//函数作用：检索手机号码格式是否有效
		checkMobile:function (obj,isCheckBool)
		{
			var val = getCheckStr(obj);
			if(!isCheckBool && (val == '' || val == null)) return true;
			return /^0?1[34578]\d{9}$/.test(val);
		},
        checkMobilePhone:function(obj,isCheckBool)
        {
            return checkfns.checkMobile(obj,isCheckBool) || checkfns.checkPhone(obj,isCheckBool);
        },
		//函数作用：检索是否有效的数字checkNumber
		checkNumber:function (obj,isCheckBool) 
		{
			var val = getCheckStr(obj);
			if(!isCheckBool && (val == '' || val == null)) return true;
			return /^\d+$/.test(val);
		},
		//函数作用：检索是否为正数checkPositiveNumber
		checkPositiveNumber:function(obj,isCheckBool)
		{
			var val = getCheckStr(obj);
			if(!isCheckBool && (val == '' || val == null)) return true;
			return  /^[0-9]*[1-9][0-9]*$/.test(val);
		},

		//函数作用：检索是否有效的钱格式
		checkMoney:function (obj,isCheckBool) 
		{
			var val = getCheckStr(obj);
			if(!isCheckBool && (val == '' || val == null)) return true;
			return /^\d+.?\d{0,2}?$/.test(val);
		},
		//函数作用：检索url地址是否有效
		checkUrl:function (obj,isCheckBool)
		{
			var val = getCheckStr(obj);
			if(!isCheckBool && (val == '' || val == null)) return true;
			if(/^\s*\w{3,6}:\/\/\s*$/.test(val)) return false;
			return /^\s*(\w{3,6}:\/\/)?([\w-]+(\.[\w-]+)+(:\d+)?(\/[\w-.\/\?%&=\u4e00-\u9fa5]*)?)?\s*$/i.test(val);
		},
		
		//函数作用：检索QQ或MSN
		checkQqMsn:function (obj,isCheckBool)
		{
			var val = getCheckStr(obj);
			if(!isCheckBool && (val == '' || val == null)) return true;
			return /(^[1-9]\d{4,10}$)|(^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$)/.test(val);
		},
		
		//函数作用：检索文件后缀名是否有效
		checkFile:function (obj,suffix,isCheckBool)
		{
			suffix = suffix || 'jpg,jpeg,gif';
			var val = getCheckStr(obj);
			if(!isCheckBool && (val == '' || val == null)) return true;
			suffix = new RegExp('\\.'+suffix.replace(/\,/g,'$|\\.')+'$','i');
			return suffix.test(val);
		},
		// 检查营业执照号码
		checkLicense:function (obj,isCheckBool)
		{
			var val = getCheckStr(obj);
			if(!isCheckBool && (val == '' || val == null)) return true;
			return !/^[\da-zA-Z]{13,20}$/.test(val);
		},
        // 检测是否为有效日期
        checkDate:function(obj,isCheckBool)
        {
            var val = getCheckStr(obj);
            if(!isCheckBool && (val == '' || val == null)) return true;
            return /\d{4}-\d{1,2}-\d{1,2}/.test(val);
        },
		//检测是否包含联系方式
		isHasContact:function (obj,isCheckBool) {
			var val = getCheckStr(obj);
			if(!isCheckBool && (val == '' || val == null)) return true;
			val = val.replace(/(\s*)/g,'');//先去掉空格再判断
            var a = /[1-9][0-9]{4,}|\d{3}-\d{8}|\d{4}-\{7,8}|\s*\w+([-+.]\w+)*@\w+([-.]\w+)*(\.\w+([-.]\w+)*){1,2}\s*/i.test(val);
            val = val.replace(/(\-*)/g,'');
            var b = /(0)?1([3|4|5|7|8])+([0-9]){9,10}/.test(val);
			return a||b;
		},

        //检测是否包含联系方式（不检测QQ）
        isHasContact2:function (obj,isCheckBool) {
            var val = getCheckStr(obj);
            if(!isCheckBool && (val == '' || val == null)) return true;
            val = val.replace(/<(?:.|\n)*?>/gm,'').replace(/(\s*)/g,'');//先去掉空格再判断
            var a = /(0)?1([3|4|5|7|8])+([0-9]){9,10}|\d{3}-\d{8}|\d{4}-\{7,8}|\s*\w+([-+.]\w+)*@\w+([-.]\w+)*(\.\w+([-.]\w+)*){1,2}\s*/i.test(val);
            return a;
        },
		
		//函数作用: 计算用户输入的字符数
		computeChar:function (obj) 
		{
			var val = getCheckStr(obj);
			return val.length;
		},
        //计算编辑器的字数
        computeWord:function(obj){
            var len = window.KE.count('info','text');
            return len;
        },
        computeHtml:function(obj){
            var len = window.KE.count('info','html');
            return len;
        },
		//函数作用: 计算用户输入的字节数
		computeBChar:function (obj) 
		{ 
			var val = getCheckStr(obj);
			return val.replace(/[^\x00-\xff]/g,"~^").length;
		},
		//函数作用: 检测是否等于检测值
		valueCheck:function (obj,checkStr)
		{
			obj = getCheckStr(obj);
			if(typeof checkStr == 'string') checkStr = unescape(checkStr);
			return checkStr == obj.replace(/^\s+|\s+$/,'');
		},
		//函数作用: 检测是否包含检测字符中
		inValue:function (obj,checkStr)
		{
			var val = getCheckStr(obj);
			if(typeof checkStr == 'string') checkStr = unescape(checkStr);
			return val.replace(/^\s+|\s+$/,'').indexOf(checkStr) != -1;
		},
        regCheck:function (obj,regStr,isCheckBool) {
            var re = new RegExp(regStr,'i');
            var val = getCheckStr(obj);
            if(!isCheckBool && (val == '' || val == null)) return true;
            return re.test(val);
        },
		evalValue:function(obj,checkStr)
		{
			var checkObj = null;
			obj = getCheckStr(obj);
			if(typeof checkStr == 'string') checkStr = unescape(checkStr);
			var operateor = '==';
			if(/^([\!<>]?={1,3})(.+)$/.exec(checkStr))
			{
				operateor = RegExp.$1;
				checkStr = RegExp.$2;
			}
			else if(/^(.+)([\!<>]?={1,3})$/.exec(checkStr))
			{
				operateor = RegExp.$2;
				checkStr = RegExp.$1;
			}
			if(checkStr != '')
			{
                
				try{checkStr = eval(checkStr);}catch(e){}   //获取操作符一侧的表达式
			}
			if(typeof checkStr == 'function') checkStr = checkStr();
			if(typeof checkStr == 'boolean') return checkStr;//布尔值直接返回
			else if(typeof checkStr == 'undefined') return false; //异常返回false
			else if(checkStr === null) return false;
			else
			{
				if(typeof checkStr == 'object')
				{
					checkObj = checkStr;
					if(typeof checkStr.test == 'function') return checkStr.test(obj);  //正则时
					else if(typeof checkStr.value != 'undefined') checkStr = checkStr.value;
					else if(typeof checkStr.innerHTML != 'undefined') checkStr = checkStr.innerHTML;
				}
				if(/^\d{2,4}[\-\/]\d{1,2}[\-\/]\d{1,2}\s?(\d{1,2}:\d{1,2}:?\d{1,2}?)?$/.test(obj)) //日期
				{
					obj = obj.replace(/[^\d]/g,'');
					checkStr = checkStr.replace(/[^\d]/g,'');
					if(obj.length > checkStr.length)
						checkStr = checkStr.substr(0,obj.length);
					else if(obj.length < checkStr.length)
						obj = obj.substr(0,checkStr.length);
				}
				//数值与日期
				if(/^[\d\-\.]+$/.test(obj))
				{
					//数值值为空时调用
					if(checkStr === '' && checkObj)
					{
						//_C.checkInput(checkObj,1);
						return false;
					}
					return eval("parseFloat('"+obj+"')"+operateor+"parseFloat('"+checkStr+"')");
				}
				else //字符比较
					return eval("'"+obj.replace(/'/g,"\\'")+"'"+operateor+"'"+checkStr.replace(/'/g,"\\'")+"'");;
			}
		}
	};
	
	var defaulAlertStr={isBlank:'不能为空',checkWord:'不能含有汉字',checkEnWord:'只能由英文、数字、下划线的组合',checkMail:'格式不正确',checkPwd:'不能含有空白字符',checkPhone:'格式不正确',checkMobile:'格式不正确',checkNumber:'只能为数字',checkPositiveNumber:'只能为正数',checkUrl:'格式不正确',computeChar:['不能小于{X}个字符','不能大于{X}个字符','请输入{X}至{X}个实际字符'],computeBChar:['不能小于{X}个字节','不能大于{X}个字节','请输入{X}至{X}个字节'],checkFile:'只能上传"jpg,jpeg,gif"格式的文件',checkMoney:'格式不正确',regCheck:'格式不正确'};
    	
	$(function() {		
		$(":input[defaultShow]").on("blur",function(){
		   if (this.tagName != 'SELECT' && this.type!="checkbox" && this.type!="radio") $(this).removeClass("C_F_I_HOVER");
		  var msgId = ($(this).attr('errShowId')||($(this).attr('name')?$(this).attr('name'):$(this).attr('id'))) + '_err_text';
		  $('#'+msgId).has('div.form-yes').remove();       
		});		
		 //输入框中  灰色默认提示值
		$(":input[defValue]").on("blur",function(){
		   if (this.tagName != 'SELECT' && this.type!="checkbox" && this.type!="radio") {
			   $(this).removeClass("C_F_I_HOVER"); 
			   return;
		   }
		   if (this.value=='') {      
			  $(this).val($(this).attr("defValue")).addClass("font_gray");
		   }        
		});



	//检测输入框内空：checkitem为检测属性,cnName为中文名称 如:<input name="XXX" cnName="名称" checkitem="isBlank:'T|提示信息'">
	//checkItem使用格式为：
	//	1.检测方法名称:检测返回值 如 isBlank:true 或 isBlank:false 此时检测提示信息为由defaulAlertStr定义提示信息
	//	2.检测方法名称:'[TF]|提示信息' 如 检测方法返回值为真时为 isBlank:'T|提示信息' 为假时 isBlank:'F|提示信息'
	//	3.检测字节或字符数时 [computeChar|computeBChar]:'>20<50|提示信息' 其中 >20 为检测是否大于20,<50 为检测是否小于50，如果检测值为假则显示提示信息（没有则显示默认提示信息）
	//	4.检测文件后缀名时 如 checkFile:[true|false] 或 checkFile:'[T|F]|jpg,gif|提示信息' [T|F]没有时默认为T 检测值为假则显示提示信息（没有则显示默认提示信息）
	//	5 input的类型为checkbox或radio时 checkitem(checkItem的值为提示信息)为属性时，为检测是否已勾选
		$(":input[checkitem]").on("blur",function(){
			var strCheck = $(this).attr('checkitem');
			try
			{
				var oCheck = eval('({'+strCheck.replace(/^\,+|\,+$/g,'')+'})');  //IE9 字符串长时 耗内存大 可以用JSON.parse解析
			}
			catch (err){ alert($(this).attr('name')+' .checkitem格式有错误!');}
		    var cname = $(this).attr('cnName')?$(this).attr('cnName'):'';
			if ($(this).val()==$(this).attr("defValue")) $(this).val(''); //输入框中是默认提示信息时
			var that=this;
			var f=false; //是否符合校验规则值
			var e_str = '';//错误提示文字
			$.each(oCheck, function(k, v){
				if (v=='') return true;
				if(that.tagName == 'INPUT' && (that.type=="checkbox" || that.type=="radio"))
			    {
					var name = $(that).attr('name');
					var cs=$(that).parent().parent().find('input[name='+name+']:checked');
					if (cs.length==0&&strCheck.indexOf('isBlank') != -1) //这一组选项中 无选择，设置了为空时错误提示 require
					{
						var params = oCheck["isBlank"].split("|");
						if (!/^[TF]$/.test(params[0])) alert($(that).attr('name')+' .checkitem '+k+':有错误!');	
						e_str = params[1];//错误提示
						f=true;
					}
						
			    } else {
					var checkFunc = checkfns[k];
					//返回布尔值的函数
					if ($.inArray(k, ["isBlank","isSimple","checkWord","checkEnWord","checkMail","checkPwd","checkPhone","checkMobile","checkMobilePhone","checkNumber","checkPositiveNumber","checkMoney","checkUrl","checkQqMsn","checkFile","checkLicense","checkDate","isHasContact","isHasContact2","valueCheck","inValue","evalValue","regCheck"])!=-1)
					{
						var params = v.split("|");
						if (!/^[TF]$/.test(params[0])) alert($(that).attr('name')+' .checkitem '+k+':有错误!');						
						var b = params[0]==='T',c=params[1],d;
						if (params[1])
						{
                            if (/^[TF]$/.test(params[1]))
                            {
                                c = params[1]==='T';
                            } else {
                                c = params[1];
                            }
						}
						if (params[2]&&/^[TF]$/.test(params[2])&&(k=='checkFile'||k=='regCheck'))
						{
							d=params[2]==='T';
						}
						//得到错误提示  提示文字在最后 若未设置为默认错误提示
						var str = params.pop(); 
						if (params.length>0&&!/^[TF]$/.test(str))   
						{
							e_str = str;
						} else {
							e_str = cname+defaulAlertStr[k];
							if (k=='checkFile') e_str = e_str.replace('"jpg,jpeg,gif"','"'+c+'"'); //校验函数checkFile时 c为扩展名列表
						}
						f = checkFunc(that,c,d)==b; //上列校验函数最多三个参数
						
					} else if (k == 'computeChar' || k == 'computeBChar' || k=='computeWord' || k=='computeHtml')
					{
						var params = v.split("|");
                        var a = params[0].match(/([><]\d+)/g);
                        if(a.length > 1)
						{
							if(a[0].substr(0,1) == '>') var minj = parseInt(a[0].substr(1)); else var maxj = parseInt(a[0].substr(1));
							if(a[1].substr(0,1) == '>') var minj = parseInt(a[1].substr(1)); else var maxj = parseInt(a[1].substr(1));
						}
						else
						{
							if(a[0].substr(0,1) == '>') var minj = parseInt(a[0].substr(1)); else var maxj = parseInt(a[0].substr(1));
						}
						if(minj && maxj)
						{
							if(checkFunc(that) < minj || checkFunc(that) > maxj)
							{
								if(/^([><]\d+){1,2}\|/.test(v)) {
                                    e_str = v.replace(/^([><]\d+){1,2}\|/,'').split(',');
                                    if (e_str.length==1||checkFunc(that) < minj)
                                        e_str = e_str[0];
                                    else 
                                        e_str = e_str[1];

                                }
								else
									e_str = cname+(defaulAlertStr[k]+'').replace('{X}',minj).replace('{X}',maxj).replace('{X}',minj).replace('{X}',maxj);
								f=true;
							}
						}
						else if(minj)
						{
							if(checkFunc(that) < minj)
							{
								if(/^([><]\d+){1,2}\|/.test(v)) 
									e_str = v.replace(/^([><]\d+){1,2}\|/,'');
								else 
									e_str = cname+(defaulAlertStr[k]+'').replace('{X}',minj);
								f=true;
							}
						}
						else if(maxj)
						{
							if(checkFunc(that) > maxj)
							{
								if(/^([><]\d+){1,2}\|/.test(v)) 
									e_str = v.replace(/^([><]\d+){1,2}\|/,'');
								else 
									e_str = cname+(defaulAlertStr[k]+'').replace('{X}',maxj);
								f=true;
							}
						}

					}

				}
				if (f) return false;
            });
            var p = $(this).parent();
            if(this.type=='radio'){
                p = p.parent();
            }
			var msgId = ($(this).attr('errShowId')||($(this).attr('name')?$(this).attr('name'):$(this).attr('id'))) + '_err_text';
			$('#'+msgId).remove();
			    
			if (!f)   //符合全部校验函数规则
			{
                var sucFuncName = $(this).attr('sucFunc');
                if(sucFuncName){
                    window[sucFuncName]();
                }
				if (this.tagName != 'SELECT' && this.type!="checkbox" && this.type!="radio") {
					$(this).removeClass("C_F_I_HOVER");
					$(this).removeClass("C_F_I_ERR");
			    }
				p.append('<SPAN style="float: left" id="'+msgId +'"><div class="form-ok">&nbsp;</div></SPAN>');
				return true;
               
			} else {
                var errFuncName = $(this).attr('errFunc');
                if(errFuncName){
                    window[errFuncName]();
                }
				if (this.tagName != 'SELECT' && this.type!="checkbox" && this.type!="radio") {
					$(this).removeClass("C_F_I_HOVER");
					$(this).addClass("C_F_I_ERR");
			    }
				p.append('<SPAN style="float: left" id="'+msgId +'"><a name="mark'+msgId +'"></a><div class="form-no">'+e_str+'&nbsp;</div></SPAN>');                
				return false;
			}
		           
		});

		//输入框中去掉  灰色默认提示值
		$(":input[defValue]").on("focus",function(){
		   if (this.tagName != 'SELECT' && this.type!="checkbox" && this.type!="radio") {
			   $(this).removeClass("C_F_I_ERR");
			   $(this).addClass("C_F_I_HOVER");
			   return;
		   }      
		   if (this.value==$(this).attr("defValue")) $(this).val("").removeClass("font_gray");       
		});
		//默认提示信息
		$(":input[defaultShow]").on("focus",function(){
		   if (this.tagName != 'SELECT' && this.type!="checkbox" && this.type!="radio") {
			   $(this).removeClass("C_F_I_ERR");
			   $(this).addClass("C_F_I_HOVER"); //选中效果 菜单 复选项 单选项不应用
		   }
		   var showtext = $(this).attr('defaultShow');
		   if (showtext=='') return;
		   var p = $(this).parent();
		   var msgId = ($(this).attr('errShowId')||($(this).attr('name')?$(this).attr('name'):$(this).attr('id'))) + '_err_text';
		   if ($('#'+msgId).length>0) $('#'+msgId).remove();
		   p.append('<SPAN style="float: left" id="'+msgId +'"><div class="form-yes">'+showtext+'&nbsp;</div></SPAN>');
		});
	});

     return function() {
		 var f=true;
         var hashmark=null;
		 $(":input[checkitem]").each(function() {
			   f=$(this).triggerHandler("blur");
               if (!hashmark && !f)
               {
                    var msgId = ($(this).attr('errShowId')||($(this).attr('name')?$(this).attr('name'):$(this).attr('id'))) + '_err_text';
                   hashmark = 'mark'+msgId;
               }
		       return f;
		 });
		 if (!f)
		 {
             if (hashmark && !$("#"+hashmark.slice(4)).isOnScreen())
             {
                  global.location.hash=hashmark;
                  global.location = global.location; //兼容chrome
                  //$("#"+hashmark.slice(4,-9)).filter(":input[type=text]").focus(); //若设置了defaultShow则看不到错误提示，故注释掉
             }
		 } else {
             //global.location.hash='';
         }
		return f;
	 };
})(this, this.jQuery);